home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-20
/
rs0422.zip
/
ROSEZSW
/
LOADER.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-11-15
|
12KB
|
436 lines
/*
* Copyright 1988 by the Radio Amateur Telecommunications Society
* and Thomas A. Moulton, W2VY
*
* This software may only be modified, copied, distributed or
* executed for non-profit purposes by individuals operating
* systems in the Amateur Radio Service. Credit to the
* author(s) and to the Radio Amateur Telecommunications Society
* must be made in modules where RATS provided software is used,
* and in any announcements and documentation.
*
* As a non-profit, research and development organization, the
* Radio Amateur Telecommunications Society distributes software
* in both executable and source forms. This policy is in place
* to encourage the development and distribution of OSI-based,
* networking tools. In order to protect the interests of the
* Society and the authors, we have placed some conditions
* of use on the software. Other groups are encouraged
* to place the same or similar guidelines on
* software they produce.
*
* The Radio Amateur Telecommunications Society reserves the right
* to specify and alter the terms under which software provided by
* the Society may be used. This policy is consistent with the
* objective of uniform and consistent "Open Systems Interconnections."
*
* All acceptable Amateur Radio related uses of this software
* will be outlined in the "ROSE Implementer's Guide". Individuals
* or organizations wishing to add to, or modify the provisions of
* the guide to accommodate local or evolutionary requirements
* should document the proposed change(s) and forward them to the
* Society. If accepted, written notification will be provided by
* the Society to the submitting organization or individual(s).
* The Society will then issue a "ROSE Implementer's Guide Change
* Notice". Periodically, the Society will re-issue the "ROSE
* Implementer's Guide" and incorporate the text of the change
* notices. This procedure has been put in to place to ensure
* compatibility between systems and to ensure their "Openness"
* and interoperability.
*
* No part of this software may be used in other packages
* without prior authorization from the author or the Society.
* Software incorporating this module, all or in part, must be
* provided to the Society prior to distribution or use by
* anyone not directly involved in testing of the revised
* environment. Current releases of the combined software must
* be provided to the Society in both source and executable
* forms. Adequate documention to produce an executable module
* from the provided source must also be included.
*
* Non-Amateur Radio non-profit uses may be authorized on a case
* by case basis. Inquiries for such use may be made in writing
* to the Society. Non-commercial uses consistent with the
* general principles of Open Systems Interconnection Reference
* Model will be generally considered with favor.
*
* Commercial licensing of the software is also available based
* on normal commercial terms. Licensing inquiries should be
* directed to the Society. Commercial licensing of the standard
* software will be done in situations which materially benefit
* the Amateur Radio Packet Network. Additional licensing is
* reserved by the individual authors.
*
* The Radio Amateur Telecommunications Society provides this software
* on an "as is" basis. The Society assumes no liability for
* loss incurred through the use of this software. Amateur Radio
* use of this software implies non-commercial and voluntary
* development, deployment and use of this software in a "Amateur",
* non-commercial service. Commercial users are encouraged to
* inspect their copies of the source code. Source code modification
* licenses are available if a combined Object and Source Code
* license was not originally established.
*
* The Society may be contacted by writing or calling at:
*
* The Radio Amateur Telecommunications Society
* 206 North Vivyen Street.
* Bergenfield, New Jersey 07621
*
* Telephone: 201-387-8896
*
*/
#include "data.h"
#include "buffer.h"
#include "iface.h"
#include "timer.h"
#include "ax25.h"
#include "ax25l2.h"
#include "l3struc.h"
#include "x25cause.h"
#include "l3calls.h"
#include "tx.h"
#include "upfcn.h"
extern struct datastr *l2_user_info, l2_info;
extern int maxfcn;
extern struct upfcn *spcfcn[];
#define bt_clrbas() free_stuff(&ld_membase)
#define bt_clrdta() free_stuff(&save_bt_data)
struct datastr *mkpkt();
unsigned char *malloc(), *calloc();
void free();
int passgen(), passvfy();
int rst_boot(), clr_boot(), con_boot(), recv_boot(), send_boot();
int NULLPKT(), NULLFCN();
struct upfcn loader={
{{0x98,0x9e,0x82,0x88,0x8a,0xa4}, {0x00}}, /* LOADER-0 */
rst_boot, clr_boot, con_boot, recv_boot, send_boot, NULLFCN, NULLPKT,
"LOADER - Program Interface Ver 1.1\r"
};
char Entry[]="Entry #? ";
char entry[10];
char bt_busy;
char bt_state;
struct datastr *bt_in;
char bt_cmd;
char bt_obj;
int bt_len;
int bt_pos;
unsigned char *bt_data, *save_bt_data;
unsigned char bt_checksum;
char bt_high;
unsigned char bt_chv;
int ld_memsiz, ld_relen;
unsigned int *ld_membase;
unsigned char passkey[16];
int
hexch(ch)
unsigned char ch;
{
if (ch>0x39) ch -= 7;
if (ch<0x30 || ch>0x3f) return -1;
return (ch-0x30);
}
int
xch(val)
unsigned char val;
{
val = (val & 0x0f);
if (val > 9) val += 7;
return (val + 0x30);
}
putxch(p,val)
register struct datastr *p;
int val;
{
bappch(p,xch(val >> 4));
bappch(p,xch(val));
}
putxint(p,val)
register struct datastr *p;
int val;
{
putxch(p,val); /* Low byte Low address */
putxch(p,(val>>8));
}
struct datastr *
info_pkt()
{
return (dup_pkt(&l2_info));
}
int
con_boot(vcx)
struct VCS *vcx;
{
register struct VCS *vcp;
static struct VCS *vc;
vc=vcx;
vcp=vc->peer;
if (!vcp) return;
puthex2("con",vc,"at",fn);
send_l3(vcp,info_pkt());
if (bt_busy) vc_clear(vc, Number_Busy);
else {
bt_busy=1;
bt_state = passgen(vcp,passkey);
}
}
int
clr_boot(vc,c)
struct VCS *vc;
int c;
{
bt_clrbas();
bt_clrdta();
bt_busy=0;
set_p(vc, P1, 0);
}
int
recv_boot(vc,pkt)
register struct VCS *vc;
struct datastr *pkt;
{
if (vc) send_l3(vc->peer,NULL); /* Kick transmitter */
/* if (vc) if (vc=vc->peer) (*vc->SEND)(vc,NULL); /* Kick transmitter */
}
int
rst_boot(vc)
register struct VCS *vc;
{
set_d(vc, D1, 0);
vc=vc->peer;
/* if (vc) /* Check for Peer */
send_l3(vc, mkpkt("\rRESET\r"));
}
int
unload_ok()
{
return 1;
}
bt_is_ok(vc)
struct VCS *vc;
{
send_l3(vc,mkpkt("OK\r"));
}
int
vc_clear0(vc)
struct VCS *vc;
{
/* vc_clear(vc, DTE_Orig); */
set_p(vc, P6, DTE_Orig);
}
int
send_boot(vc, pkt)
register struct VCS *vc;
struct datastr *pkt;
{
static int i, ch;
puthex2("send fig",vc,"",pkt);
vc_queue_data(vc,pkt);
while ((bt_in = vc->tx_queue)) /* There is stuff waiting */ {
vc->tx_queue=bt_in->next;
bt_in->next=NULL;
if (bt_state == 0) /* Check for correct Password */ {
#if 0
bt_state++;
#else
if (passvfy(&bt_in, passkey)) {
bt_state=1;
bt_is_ok(vc->peer);
} else /* Dump this Turkey */ {
queue(NULL,vc_clear0,0,vc);
return 0;
}
#endif
}
if (bt_in) /* We have more in this packet */ {
while ((ch=bgetch(&bt_in)) != EOF) {
puthex2("loop",ch,"",bt_in);
if (ch > 0x20) /* Allow Control chars to pass */ {
i=hexch(ch);
if (ch == 0x3a || i<0 ) bt_state=1;
if (bt_state == 1) /* Clean up */ {
bt_clrdta();
bt_data = NULL;
bt_chv = ch;
bt_high = TRUE;
} else {
if (bt_high) bt_chv = i<<4;
else bt_chv += i;
bt_high = !bt_high;
}
if (bt_high) bt_next(vc, bt_chv);
}
}
}
}
return 256; /* We are never busy! */
}
/* bt_state has the following meaning
/* 1 - Searching for a : (Start of record)
/* 2 - Next byte read is the command
/* 3 - Next byte read is the object we are working with
/* 4 - Next byte read is the low byte of length !Low byte Low address!
/* 5 - Next byte read is the high byte of length
/* 6 - Next byte read is additional data
/* 7 - Processing request
*/
#define MAXCMD 3
#define MAXOBJ 15
bt_next(vc,chv)
struct VCS *vc;
unsigned char chv;
{
static char err;
static int len;
register struct VCS *vcp;
int do_boot();
err=0;
vcp=vc->peer;
puthex2("next",bt_state,"ch",chv);
switch (bt_state) {
case 1: if (chv != 0x3a) bt_state=0;
break;
case 2: bt_cmd=chv;
if (chv > MAXCMD) err=1;
break;
case 3: bt_obj=chv;
break;
case 4: bt_len= chv; /* Low byte Low address */
break;
case 5: bt_len += (chv<<8);
bt_pos=0;
bt_checksum=0;
if (bt_cmd == 1 && bt_obj == 0x42) /* Code */ {
if (ld_memsiz < bt_len) err = 9;
else len = ld_memsiz;
} else len=bt_len;
if (len) {
bt_data=save_bt_data=calloc(1,len);
if (bt_data == NULL) err = 3;
}
if (bt_len == 0) bt_state++; /* No data field */
break;
case 6: bt_data[bt_pos]=chv;
bt_pos++;
bt_checksum += chv;
if (bt_pos != bt_len) bt_state--;
break;
case 7: bt_checksum += chv;
if (bt_checksum != 0) err=4;
else err=do_boot(vcp);
if (!err) bt_is_ok(vcp);
bt_clrdta();
bt_state=0;
break;
}
if (err) {
if (vcp) send_l3(vcp,l_message(" Error ", err));
bt_state=0;
bt_clrbas();
}
bt_state++;
puthex2("exit",bt_state,"err",err);
}
int
do_boot(vc)
struct VCS *vc;
{
static int i;
static struct datastr *bp;
static unsigned int *rel;
int bt_usr_inf();
if (bt_cmd == 0) /* Print list */ {
ld_memsiz = ld_relen = 0;
bp = new_buffer(256);
for (i=0;i<maxfcn;i++) {
entry[7] = ('0' + (i>9 ? i+7 : i));
bappstr(bp, entry);
bp = bappstr(bp, spcfcn[i]->title);
}
send_l3(vc,bp);
} else if (bt_cmd == 1) /* Load request */ {
if (bt_obj == 0) /* Load User Info Text Message */ {
i=bt_usr_inf();
sumchk();
return i;
} else
if (bt_obj == 0x41) /* Sizing info */ {
#ifndef z80
return 15;
#endif
if (maxfcn >= 15) return 14;
ld_memsiz = *(unsigned int *)bt_data;
bt_data += 2; /* Skip an Int */
ld_relen = *(unsigned int *)bt_data;
} else if (bt_obj == 0x42) /* Code Segment */ {
if (maxfcn >= 15) return 14;
bt_clrbas();
ld_membase = (unsigned int *)bt_data;
save_bt_data = NULL; /* Don't free the memory */
} else if (bt_obj == 0x43) /* Relocation data */ {
if (bt_len != ld_relen*2 || ld_membase == NULL
|| bt_data == NULL) return 13;
rel = (unsigned int *)bt_data;
for (i=0;i<ld_relen;i++, rel++) /* Relocate an address */ {
*(int *)((int)ld_membase + (int)*rel) += (unsigned int)ld_membase;
}
spcfcn[maxfcn]=(struct upfcn *)ld_membase;
ld_membase = NULL;
(*spcfcn[maxfcn]->init)(); /* Init it, if needed */
maxfcn++; /* It is now valid */
} else return 15;
} else if (bt_cmd == 2) /* Delete application */ {
ld_memsiz = ld_relen = 0;
if (bt_obj < 0 || bt_obj >= maxfcn || maxfcn == 1) return 12;
if ((*spcfcn[bt_obj]->unload)()) /* Unloaded OK */ {
free(spcfcn[bt_obj]);
maxfcn--;
/* Move others up */
for (i=bt_obj;i<maxfcn;i++) spcfcn[i]=spcfcn[i+1];
spcfcn[maxfcn+1]=NULL;
}
} else return 16;
return 0;
}
bt_usr_inf()
{
register struct datastr *bp;
if (l2_user_info != &l2_info) free_pkt(l2_user_info);
l2_user_info=info_pkt();
if (bt_len) if (!(bp=new_buffer(bt_len))) return 3;
while (bt_len--) bappch(bp, *bt_data++);
l2_user_info=binsert(l2_user_info,bp);
return 0;
}